package com.lebang.service.buss;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lebang.common.util.RequestUtil;
import com.lebang.common.utils.*;
import com.lebang.common.validcode.Maths;
import com.lebang.common.validcode.RedisLogin;
import com.lebang.common.validcode.ValidCodeUtil;
import com.lebang.component.RedisClient;
import com.lebang.component.RedisSdkClient;
import com.lebang.component.SendComponent;
import com.lebang.component.UMengPushComponent;
import com.lebang.configuration.datasource.DataSource;
import com.lebang.domain.*;
import com.lebang.entity.BlackRecord;
import com.lebang.entity.FastLoginRecord;
import com.lebang.entity.RequestHeaders;
import com.lebang.entity.buss.RecordMsg;
import com.lebang.entity.member.LbbMember;
import com.lebang.entity.member.LbbMemberFeedback;
import com.lebang.entity.member.LbbMemberNotice;
import com.lebang.example.BlackVagueIpaddrRecordExample;
import com.lebang.example.LbbMemberExample;
import com.lebang.mapper.*;
import com.lebang.model.IpAdressModel;
import com.lebang.model.MsgRequest;
import com.lebang.model.RequestUserInfo;
import com.lebang.model.WeixinInfo;
import com.lebang.model.back.Result;
import com.lebang.model.cences.OsCencesModel;
import com.lebang.model.enums.Booleans;
import com.lebang.model.enums.Gender;
import com.lebang.model.enums.InviteEnum;
import com.lebang.model.enums.NoticeType;
import com.lebang.model.enums.buss.UserStatus;
import com.lebang.model.vo.buss.MemberListVo;
import com.lebang.model.vo.buss.MemberSearchVo;
import com.lebang.service.OceanEngineService;
import com.lebang.service.mongodb.BlackRecordMongodb;
import com.lebang.service.sys.RegisterWhiteImeiService;
import com.lebangweb.common.TextUtil;
import com.lebangweb.common.UUIDUtil;
import com.lebangweb.encrypt.MessageDigestUtil;
import com.lebangweb.network.HttpUtils;
import com.lebangweb.response.Callback;
import com.lebangweb.response.JsonData;
import org.apache.commons.collections4.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

import static com.lebang.controller.sys.BlackVagueIpaddrRecordController.BLACK_IP_ADDR;

@Service
public class MemberService {
    @Autowired
    private BlackVagueIpaddrRecordMapper blackVagueIpaddrRecordMapper;
    @Autowired
    private RedisSdkClient redisSdkClient;
    @Autowired
    private WhiteIpMapper whiteIpMapper;

    @Autowired
    private LbbMemberNoticeMapper memberNoticeMapper;

    @Autowired
    private LbbMemberTradeMapper memberTradeMapper;


    @Autowired
    private RedisClient redisClient;

    @Autowired
    private LbbMemberMapper memberMapper;

    @Autowired
    private SendComponent sendComponent;
    public static final String MEMBER_LOGIN_RECORD = "member_login_record:";
    @Autowired
    private UMengPushComponent uMengPushComponent;
    @Autowired
    private MemberLoginRecordMapper memberLoginRecordMapper;
    @Autowired
    private RegisterWhiteImeiService registerWhiteImeiService;
    @Autowired
    private ActiveMemberMapper activeMemberMapper;
    @Autowired
    private PhoneLoginRecordMapper phoneLoginRecordMapper;
    @Autowired
    private IpLoginRecordMapper ipLoginRecordMapper;
    @Autowired
    private ValidCodeUtil validCodeUtil;
    @Autowired
    private OceanEngineService oceanEngineService;
    @Autowired
    private FastLoginRecordMapper fastLoginRecordMapper;
    @Autowired
    private MemberDeviceInfoMapper memberDeviceInfoMapper;
    @Autowired
    private InviteReleaseMapper inviteReleaseMapper;
    @Autowired
    private MemberHeaderHistoryMapper memberHeaderHistoryMapper;
    @Autowired
    private MemberWalletMapper memberWalletMapper;
    @Autowired
    private MemberPointInfoMapper memberPointInfoMapper;
    @Value("${info.shanyan.appId}")
    private String appId;
    @Value("${info.shanyan.appKey}")
    private String appKey;
    //创建应用时填入的rsa公钥对应的私钥字符串
    public static final String PRIVATE_KEY = "";
    // 免密登录后台url
    public static final String FLASH_LOGIN_URL = "https://api.253.com/open/flashsdk/mobile-query";

    public Map<String, Object> list(MemberSearchVo vo) {
        Map<String, Object> data = new HashMap<String, Object>(1);
        Integer total = memberMapper.total(vo);
        List<MemberListVo> rows = memberMapper.pagging(vo);
        data.put("total", total);
        data.put("rows", rows);
        return data;
    }

    /**
     * 用户消息列表
     *
     * @param userid
     * @param appid
     * @param page
     * @param size
     * @return
     * @author weizx
     * @date 2018年7月26日 上午11:08:14
     */
    public List<Map<String, Object>> notices(String userid, String appid, Integer page, Integer size) {
        page = (null == page || 0 >= page) ? 1 : page;
        size = (null == size || 0 >= size) ? 20 : size;
        return memberNoticeMapper.list(userid, appid, page, size);
    }

    public void notice(LbbMemberFeedback mf, String title, String desc) {

        LbbMember member = this.selectMemberById(mf.getUserId());
        try {
            uMengPushComponent.sendAndroidCustomizedcast(title, desc, member.getMemberId());
        } catch (Exception e) {
            e.printStackTrace();
        }
        member.setNoticeCount(member.getNoticeCount() + 1);//用户的消息提示+1
        memberMapper.updateByPrimaryKeySelective(member);
        LbbMemberNotice notice = new LbbMemberNotice();//添加到消息表格里
        notice.setAppId("xianyu");
        notice.setAppStore(mf.getAppStore());
        notice.setCategory(NoticeType.Text);
        notice.setContent("");//mf.getContent
        notice.setMemberId(mf.getUserId());
        notice.setStatus("On");
        notice.setSubtitle(desc);
        notice.setTitle(title);
        notice.setHasDeleted(Booleans.False.name());
        memberNoticeMapper.insertSelective(notice);//插入消息表
    }

    //查找会员
    public LbbMember selectMemberById(String memberId) {
        try {
            return memberMapper.getMemberByMemberId(memberId);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    public LbbMember getMember(LbbMember member) {

        return memberMapper.getMember(member);
    }

    public int insertMember(LbbMember member) {
        return memberMapper.insertSelective(member);
    }

    public LbbMember getMemberByMemberId(String memberId) {
        return memberMapper.getMemberByMemberId(memberId);
    }

    public LbbMember getByinviteCode(String inviteCode) {
        return memberMapper.getByinviteCode(inviteCode);
    }

    public int updateMemberById(LbbMember member) {
        return memberMapper.updateByPrimaryKeySelective(member);
    }

    public LbbMember getMemberByPhone(String phone, String appid) {
        return memberMapper.getMemberByPhone(phone, appid);
    }

    public List<LbbMember> getInviters(String memberId, String appid) {
        return memberMapper.getInviters(memberId, appid);
    }

    public String inviteCode() {
        LbbMember member = new LbbMember();

        String icode = UUIDUtil.NS() + Maths.random(10, 99);
        boolean flag = true;
        while (flag) {
            member.setInviteCode(icode);
            LbbMember member2 = this.getMember(member);
            if (member2 != null) {
                icode = UUIDUtil.NS() + Maths.random(10, 99);
            } else {
                flag = false;
            }
        }
        return icode;
    }

    private List<String> findListByType(MsgRequest msgRequest) {
        List<String> lbbMembers;
        switch (msgRequest.getType()) {
            case 1:
                break;
            case 2:
                break;
            case 3:
                break;
            case 4:
                break;
            case 5:
                break;
            default:
                break;
        }
        lbbMembers = memberTradeMapper.selectByMsgRequest(msgRequest);
        return lbbMembers;
    }

    public int findCountByType(MsgRequest msgRequest) {
        return this.findListByType(msgRequest).size();
    }


    /**
     * 取得要通知道的用户插入到队列当中
     *
     * @param msgRequest
     * @return
     */
    public boolean sendMsByType(MsgRequest msgRequest) {
        List<String> members = this.findListByType(msgRequest);
        List<List<String>> sprateList = ListUtils.partition(members, 500);
        List<String> pushList = new ArrayList<>();
        sprateList.forEach(s -> pushList.add(String.join(",", s)));
        List<RecordMsg> recordMsgList = new ArrayList<>();
        for (String member : pushList) {
            RecordMsg recordMsg = new RecordMsg();
            recordMsg.setMemberId(member);
            recordMsg.setMsg(msgRequest.getMsg());
            recordMsg.setTitle(msgRequest.getTitle());
            recordMsgList.add(recordMsg);
            //redis管道批量写入
        }
        sendComponent.addToEventToQueue(recordMsgList);
        return true;
    }


    public boolean hasBindWeixin(String state) {
        LbbMember member = memberMapper.getMemberByMemberId(state);
        if (member != null) {
            return member.getWxStatus().equals(1);
        }
        return false;
    }

    public int bindWeixin(String memberId, WeixinInfo weixinInfo) {
        LbbMember member = memberMapper.getMemberByMemberId(memberId);
        if (member != null) {
            LbbMemberExample example = new LbbMemberExample();
            example.createCriteria().andHasDeletedEqualTo(Booleans.False.name()).andWxOpenidEqualTo(weixinInfo.getOpenId());
            long count = memberMapper.countByExample(example);
            if (count > 0) {
                return -1;
            }
            member.setWxOpenid(weixinInfo.getOpenId());
            member.setWxStatus(weixinInfo.getStatus());
            member.setNickname(weixinInfo.getNickName());
            member.setAvatar(weixinInfo.getAvatar());
            member.setGender(weixinInfo.getGender());
            memberMapper.updateByPrimaryKeySelective(member);

            return 1;
        } else {
            return 0;
        }

    }

    public String checkMemberByMemberId(String userid) {
        return memberMapper.checkMemberByMemberId(userid);
    }

    public LbbMember selectByPhone(String phone) {
        return memberMapper.selectByPhone(phone);
    }

    @Async
    public void addLoginRecord(RequestHeaders requsetHeader,String city) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
        LocalDate now = LocalDate.now();
        int time = Integer.parseInt(now.format(df));
        ActiveMember activeM = activeMemberMapper.selectOneByAppStoreAndImei(requsetHeader.getAppStore(), requsetHeader.getImei(), LocalDate.now());
        if (activeM == null) {
            int count = memberLoginRecordMapper.selectByMemberIdAndTime(requsetHeader.getImei(), time);
            if (count == 0) {
                MemberLoginRecord record = new MemberLoginRecord();
                record.setCreateTime(new Date());
                record.setModifyTime(new Date());
                record.setMemberId(requsetHeader.getUserid());
                record.setTime(time);
                record.setIp(requsetHeader.getIpAddr());
                record.setImei(requsetHeader.getImei());
                memberLoginRecordMapper.insertSelective(record);
            }
        }

        if (activeM == null) {
            ActiveMember activeMember = new ActiveMember(requsetHeader);
            IpAdressModel ipAdressModel = getIpAddr(activeMember.getIp());
            activeMember.setIpProvince(ipAdressModel.getProvince());
            activeMember.setIpCity(ipAdressModel.getCity());
            //活跃城市
            activeMember.setCity(city);

            activeMemberMapper.insert(activeMember);
        } else {
            IpAdressModel ipAdressModel = getIpAddr(requsetHeader.getIpAddr());
            activeM.setIpProvince(ipAdressModel.getProvince());
            activeM.setIpCity(ipAdressModel.getCity());
            activeM.setVersion(requsetHeader.getVersionInt());
            activeM.setIp(requsetHeader.getIpAddr());
            activeMemberMapper.updateByPrimaryKeySelective(activeM);
        }

    }

    public String getLoginKey(String brand) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
        LocalDate now = LocalDate.now();
        int time = Integer.parseInt(now.format(df));
        return MEMBER_LOGIN_RECORD + time + ":" + brand;
    }

    public LbbMember selectMemberByCode(String inviteCode) {
        return memberMapper.selectMemberByCode(inviteCode);
    }


    /**
     * 查找用户师徒
     *
     * @param memberId
     */
    public LbbMember getMemberById(String memberId) {
        LbbMember member = memberMapper.getMemberByMemberId(memberId);
        return member;
    }

    public void updateInviteById(String memberId, String inviteId, Integer inviteVersion) {
        memberMapper.updateInviteById(memberId, inviteId, inviteVersion);
    }

    public int getCountByMemberId(String memberId, LocalDateTime min, LocalDateTime max) {
        return memberMapper.getCountByMemberId(memberId, min, max);
    }

    public boolean checkTimeOut(String memberId) {
        LbbMember lbbMember = memberMapper.selectById(memberId);
        long time = lbbMember.getCreateTime().getTime();
        //1577289611时间戳2019-12-26
        return time > 1577289611000L;
    }


    /**
     * 注销用户 逻辑删除账户信息  存入tb_del_member中
     *
     * @param member
     */
    public void delMember(LbbMember member) {
        member.setHasDeleted("True");
        memberMapper.updateByPrimaryKeySelective(member);
        memberMapper.insertDelSelective(member);
    }

    /**
     * 验证一个设备号最大设备数 不能大于3
     *
     * @param imei
     * @return
     */
    public boolean checkImei(String imei) {
        if (registerWhiteImeiService.getImei(imei)) {
            return false;
        }
        return memberMapper.countByImei(imei) > 0;
    }

    /**
     * 验证支付宝账号绑定了几个咸鱼账号 不能超过2个
     *
     * @param alipay
     * @param name
     * @return
     */
    public boolean selectByAilPay(String alipay, String name) {
        LbbMemberExample example = new LbbMemberExample();
        example.createCriteria().andAlipayEqualTo(alipay).andHasDeletedEqualTo(Booleans.False.name());
        return memberMapper.countByExample(example) > 0;
    }

    public void updateByMemberId(Integer id, String status) {
        memberMapper.closeMemberId(id, status);
    }

    public LocalDateTime selectCreateById(String memberId) {
        return memberMapper.selectCreaTimeByMemberId(memberId);
    }

    public List<String> selectMasterMemberIdList(String masterPhone) {
        return memberMapper.selectMasterMemberIdList(masterPhone);
    }

    @Autowired
    private BlackRecordMongodb blackRecordMongodb;

    /**
     * 验证 该请求是否进入马甲页
     *
     * @param requestHeaders
     * @return
     */
    @DataSource("commonDB")
    public boolean checkImeiAndIpAddr(RequestHeaders requestHeaders) {
        // redisSdkClient.hgetall(BLACK_IP_ADDR+"LIST");
        boolean isBlackIp = false;
        List<BlackVagueIpaddrRecord> blackVagueIpAddrRecords = null;
        Optional<String> ipStr = Optional.ofNullable(redisSdkClient.hget(BLACK_IP_ADDR, requestHeaders.getAppStore()));
        if (!ipStr.isPresent()) {
            BlackVagueIpaddrRecordExample example = new BlackVagueIpaddrRecordExample();
            example.createCriteria().andAppStoreEqualTo(requestHeaders.getAppStore());
            blackVagueIpAddrRecords = blackVagueIpaddrRecordMapper.selectByExample(example);
            redisSdkClient.hset(BLACK_IP_ADDR, requestHeaders.getAppStore(), JSON.toJSONString(blackVagueIpAddrRecords));
        } else {
            blackVagueIpAddrRecords = JSON.parseArray(ipStr.get(), BlackVagueIpaddrRecord.class);
        }
        for (BlackVagueIpaddrRecord item : blackVagueIpAddrRecords) {
            if (requestHeaders.getIpAddr().startsWith(item.getIpAddr())) {
                isBlackIp = true;
                break;
            }
        }
        int i = memberMapper.checkImei(requestHeaders.getImei());
        int k = memberMapper.checkIpAddr(requestHeaders.getIpAddr(), requestHeaders.getAppStore());
        //查黑名单
        if (i > 0 || k > 0 || isBlackIp) {
            //查白名单
            Integer count = whiteIpMapper.selectByIp(requestHeaders.getIpAddr());
            if (count == 0) {
                //记录被拦截用户
                blackRecordMongodb.save(new BlackRecord(requestHeaders));
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }

    }

    public int updateIdCard(String memberId, String idCard, String name) {
        return memberMapper.updateIdCard(memberId, idCard, name);
    }

    public List<OsCencesModel> countOsVersionRegister(LocalDateTime star, LocalDateTime end, String brand, String osVersion) {
        return memberMapper.countOsVersionRegister(star, end, brand, osVersion);
    }

    public List<OsCencesModel> countOsRegister(LocalDateTime star, LocalDateTime end, String brand, String osv) {
        return memberMapper.countOsRegister(star, end, brand, osv);
    }

    public List<OsCencesModel> countOsActive(LocalDateTime star, LocalDateTime end, String brand, String osv) {
        return activeMemberMapper.countOsActive(star, end, brand, osv);
    }

    public List<OsCencesModel> countOsVersionActive(LocalDateTime starTime, LocalDateTime endTime, String brand, String osVersion) {
        return activeMemberMapper.countOsVersionActive(starTime, endTime, brand, osVersion);
    }

    public LbbMember getMemberByMemberIdAndVersion(String memberId, int inviteVersion) {
        return memberMapper.getMemberByMemberIdAndVersion(memberId, inviteVersion);
    }

    @Autowired
    private MemberCashWithdrawalMapper memberCashWithdrawalMapper;

    @Async
    public void is(List<String> ip) {
        AtomicInteger o = new AtomicInteger(1);
        ip.parallelStream().forEach(s -> {
            System.out.println("{}" + o.get() + "/" + ip.size() + "{}");
            JSONObject addr = OkHttpUtil.getRequest("http://apis.juhe.cn/ip/ipNew?key=06b5be8d03c08a07a659721b543e12ad&ip=" + s);
            if (addr != null) {
                if (addr.getString("resultcode").equals("200")) {
                    JSONObject d = addr.getJSONObject("result");
                    String addr1 = d.getString("Country") + d.getString("Province") + d.getString("City") + d.getString("Isp");
                    memberCashWithdrawalMapper.updateByIp(s, addr1);
                }
            }
            o.addAndGet(1);
        });


    }


    /**
     * 创建新用户对象
     *
     * @param request       请求
     * @param requsetHeader 请求头
     * @return
     */
    public LbbMember createMember(HttpServletRequest request, RequestHeaders requsetHeader, String phone) throws Exception {

        String icode = inviteCode();
        String pass = UUIDUtil.L();
        String memberId = UUIDUtil.L();
        LbbMember member = new LbbMember();
        member.setRequestUri(request.getRequestURI());
        member.setCreateTime(new Date());
        member.setBrand(requsetHeader.getBrand());
        member.setImei(requsetHeader.getImei());
        member.setAppStore(requsetHeader.getAppStore());
        member.setAlipay("");
        member.setAlipayName("");
        member.setAppId(requsetHeader.getAppid());
        member.setAvatar("");
        member.setBirthday("");
        member.setCategory("True");
        member.setGender(Gender.Unknow.name());
        member.setInviteCode(icode);
        member.setInviterId("");
        member.setMemberId(memberId);
        member.setNickname(phone);
        member.setPassword(MessageDigestUtil.encryptMD5(pass.getBytes()));
        member.setPersonId("");
        member.setPhone(phone);
        member.setRealname("");
        member.setStatus("");
        member.setUnionid("");
        member.setWeixin("");
        member.setWeixinName("");
        member.setOsVersion(requsetHeader.getOsVersion());
        member.setOsv(requsetHeader.getOsv());
        member.setInviteVersion(InviteEnum.OLD_VERSION.getIndex());
        member.setIsGraduate(InviteEnum.UN_GRADUATION.getIndex());

        IpAdressModel ipAddr = this.getIpAddr(requsetHeader.getIpAddr());
        member.setIpProvince(ipAddr.getProvince());
        member.setIpCity(ipAddr.getCity());

        insertMember(member);
        initWalletData(member.getMemberId());
        initPointData(member.getMemberId());
        return member;
    }

    public List<Map<String, String>> page(Long page, Integer limit, String search, String weixin, String alipay, String appId, String memberId) {
        return memberMapper.page(page, limit, search, weixin, alipay, appId, memberId);
    }

    public long count(String search, String weixin, String alipay, String appId, String memberId) {
        return memberMapper.count(search, weixin, alipay, appId, memberId);
    }

    /**
     * 写入手机设备登录记录
     *
     * @param phone
     * @param requestHeaders
     */
    public void insertLoginRecord(String phone, RequestHeaders requestHeaders) {
        LocalDate now = LocalDate.now();
        if (phoneLoginRecordMapper.countByImeiAndDate(now, requestHeaders.getImei()) == null) {
            PhoneLoginRecord phoneLoginRecord = new PhoneLoginRecord();
            phoneLoginRecord.setCreateTime(LocalDateTime.now());
            phoneLoginRecord.setModifyTime(LocalDateTime.now());
            phoneLoginRecord.setPhone(phone);
            phoneLoginRecord.setCreateDate(now);
            phoneLoginRecord.setImei(requestHeaders.getImei());
            phoneLoginRecordMapper.insertSelective(phoneLoginRecord);
        }

    }

    public boolean checkImeiAndPhone(String phone, RequestHeaders requestHeaders) {
        if (registerWhiteImeiService.getImei(requestHeaders.getImei())) {
            return false;
        }
        LocalDate now = LocalDate.now();
        //当前登录手机
        if(TextUtil.isEmpty(requestHeaders.getImei())){
            return false;
        }
        PhoneLoginRecord phoneLoginRecord = phoneLoginRecordMapper.selectByImeiAndDate(now, requestHeaders.getImei());
        if (phoneLoginRecord != null) {
            return !phoneLoginRecord.getPhone().equals(phone);
        }
        return false;
    }

    /**
     * 检查绑定支付宝或者微信相同身份证的个数
     *
     * @param icard
     * @param type
     * @param i
     * @return
     */
    public boolean checkByICard(String icard, Integer type, int i) {
        return memberMapper.countByICard(icard, type) > i;
    }

    /**
     * 检查时间段内ip相同的个数
     *
     * @param star
     * @param end
     * @param checkIpNum
     * @param requestUserInfo
     * @return
     */
    public boolean checkIpNumByHour(LocalDateTime star, LocalDateTime end, Integer checkIpNum, RequestUserInfo requestUserInfo) {
        if (ipLoginRecordMapper.countByTime(star, end, requestUserInfo.getIpAddr()) >= checkIpNum) {
            return true;
        } else {
            IpLoginRecord record = ipLoginRecordMapper.selectOneByMemebrId(requestUserInfo.getMemberId());
            if (record != null) {
                record.setModifyTime(end);
                record.setIp(requestUserInfo.getIpAddr());
                record.setAppStore(requestUserInfo.getAppStore());
                IpAdressModel ipAdressModel = getIpAddr(record.getIp());
                record.setIpProvince(ipAdressModel.getProvince());
                record.setIpCity(ipAdressModel.getCity());
                ipLoginRecordMapper.updateByPrimaryKeySelective(record);
            } else {
                IpLoginRecord ipLoginRecord = new IpLoginRecord();
                ipLoginRecord.setCreateTime(end);
                ipLoginRecord.setIp(requestUserInfo.getIpAddr());
                ipLoginRecord.setMemberId(requestUserInfo.getMemberId());
                ipLoginRecord.setAppStore(requestUserInfo.getAppStore());
                ipLoginRecord.setModifyTime(end);
                IpAdressModel ipAdressModel = getIpAddr(ipLoginRecord.getIp());
                ipLoginRecord.setIpProvince(ipAdressModel.getProvince());
                ipLoginRecord.setIpCity(ipAdressModel.getCity());
                ipLoginRecordMapper.insertSelective(ipLoginRecord);
            }

        }
        return false;

    }

    /**
     * 聚合获取ip位置
     *
     * @param ip
     * @return
     */
    private IpAdressModel getIpAddr(String ip) {
        IpAdressModel ipAdressModel = new IpAdressModel();

        try {
            JSONObject addr = OkHttpUtil.getRequest("http://apis.juhe.cn/ip/ipNew?key=06b5be8d03c08a07a659721b543e12ad&ip=" + ip);
            if (addr != null) {
                if (addr.getString("resultcode").equals("200")) {
                    JSONObject d = addr.getJSONObject("result");
                    ipAdressModel.setProvince(d.getString("Province"));
                    ipAdressModel.setCity(d.getString("City"));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ipAdressModel;
        }

        return ipAdressModel;
    }

    public boolean checkIpByMemberId(LocalDateTime star, LocalDateTime end, RequestUserInfo requestUserInfo) {
        return ipLoginRecordMapper.selectByMemberId(star, end, requestUserInfo.getMemberId()) != null;
    }

    public LbbMember selectByImei(String imei) {
        return memberMapper.selectByImei(imei);
    }

    public LbbMember selectByMemberId(String memberId) {
        return memberMapper.getMemberByMemberId(memberId);
    }

    /**
     * 根据用户身份证清空账号支付宝,微信绑定的身份证号
     *
     * @param idCard
     */
    public void updateIdCardByIdCard(String idCard) {
        memberMapper.updateIdCardByIdCard(idCard);
    }

    public Result<String> getlbbMember(LbbMember lbbMember, String memberId, String imei) {
        Result<String> result = new Result<>();
        if (lbbMember != null) {
            if (!lbbMember.getMemberId().equals(memberId)) {
                result.setStatus("fail");
                result.setMessage("该设备已经完成新手任务了");
                return result;
            }
        } else {
            LbbMember user = this.selectMemberById(memberId);
            if (user != null) {
                if (!user.getImei().equals(imei)) {
                    result.setStatus("fail");
                    result.setMessage("很遗憾，礼包已抢完");
                    return result;
                }
            }
        }
        return result;
    }

    /**
     * 查找未删除用户的member_id
     *
     * @return
     */
    public List<String> selectAllMember() {
        return memberMapper.selectAllMember();
    }

    /**
     * 查找用户微信昵称
     *
     * @return
     */
    public List<String> selectMemberListName() {
        return memberMapper.selectMemberListName();
    }

    /**
     * 根据师傅memberId获取徒弟个数
     *
     * @param memberId
     * @return
     */
    public int selectApprentice(String memberId) {
        return memberMapper.selectApprentice(memberId);
    }

    /**
     * 根据id获取用户手机号
     *
     * @param memberId
     * @return
     */
    public String getPhoneById(String memberId) {
        return memberMapper.selectPhoneByMemberId(memberId);
    }

    /**
     * 删除用户登录记录
     *
     * @param phone
     * @param imei
     */
    public void deleteImeiLoginRecord(String phone, String imei) {
        phoneLoginRecordMapper.deleteImeiLoginRecord(phone, imei, LocalDate.now());
    }

    /**
     * 验证码注册登录
     *
     * @param request
     * @param phone
     * @param code
     * @param params
     * @return
     * @throws Exception
     */
    public JsonData validCodeRegister(HttpServletRequest request, String phone, String code, String params) throws Exception {
        //提取头部数据
        RequestHeaders requsetHeader = RequestUtil.getHeader(request);
        // 校验验证码
        if (!validCodeUtil.checkCode(phone, RedisLogin.PHONE_NEW_LOGIN_CODE, code)) {
            return Callback.fail("invalid_code", "验证码错误！");
        }
        LbbMember member = selectByPhone(phone);
        if (member != null) {
            insertLoginRecord(member.getPhone(), requsetHeader);
            if (checkImeiAndPhone(member.getPhone(), requsetHeader)) {
                return Callback.fail("invalid_code", "一个设备只能登录一个手机号");
            }
            //销户账号再次注册登录
            if (member.getStatus().equals(UserStatus.CheckSuccess.name())) {
                member.setStatus(UserStatus.Allow.name());
                updateMemberById(member);
            }
            insertRecord(member.getMemberId(), 0);
            insertDeviceInfo(params, member.getMemberId());
            return Callback.success("200", "登录成功", member);

        } else {
            if (checkImei(requsetHeader.getImei())) {
                return Callback.fail("invalid_code", "一个设备号最多注册1个账号,有疑问请联系客服");
            }
            insertLoginRecord(phone, requsetHeader);
            if (checkImeiAndPhone(phone, requsetHeader)) {
                return Callback.fail("invalid_code", "一个设备只能登录一个手机号");
            }

            //自动注册 密码为UUID随机值
            //TODO
            member = createMember(request, requsetHeader, phone);

            insertRecord(member.getMemberId(), 0);
            //验证成功删除验证码
            validCodeUtil.cleanCode(phone, RedisLogin.PHONE_NEW_LOGIN_CODE, code);
            oceanEngineService.checkResinTear(requsetHeader, 1);
            insertDeviceInfo(params, member.getMemberId());
            //写入最近的记录
            requsetHeader.setUserid(member.getMemberId());
            insertMemberHeaderInfo(requsetHeader);
            return Callback.success("200", "登录成功", member);

        }


    }


    /**
     * 闪验登录注册
     *
     * @param request
     * @param token
     * @param parameter
     * @return
     */
    public JsonData fastRegister(HttpServletRequest request, String token, String parameter) {
        String UUID = UUIDUtil.M();
        //提取头部数据
        RequestHeaders requsetHeader = RequestUtil.getHeader(request);
        //手机号加解密方式 0 AES 1 RSA , 可以不传，不传则手机号解密直接使用AES解密
        String encryptType = "0";
        //从SDK获取的token参数
        try {
            boolean lock = redisClient.tryGetDistributedLock("LOCK:IMEI:FASTLOGIN" + requsetHeader.getImei(), UUID, 30000);
            if (!lock) {
                return Callback.fail("200", "请求过于频繁");
            }
            Map<String, String> params = new HashMap<>(1);
            params.put("token", token);
            params.put("appId", appId);
            params.put("encryptType", encryptType);//可以不传，不传则解密直接使用AES解密
            params.put("sign", SignUtils.getSign(params, appKey));
            JSONObject jsonObject = OkHttpUtil.postRequest(FLASH_LOGIN_URL, params);
            if (null != jsonObject) {
                System.out.println("response:" + jsonObject.toJSONString());
                HttpUtils.getInstance().doPost(FLASH_LOGIN_URL, params, params);
                String code = jsonObject.getString("code");     //返回码 200000为成功
                String message = jsonObject.getString("message");//返回消息
                String chargeStatus = jsonObject.getString("chargeStatus"); //是否收费
                if ("200000".equals(code)) {
                    String dataStr = jsonObject.getString("data");
                    JSONObject dataObj = JSONObject.parseObject(dataStr);
                    String mobile = dataObj.getString("mobileName");
                    String tradeNo = dataObj.getString("tradeNo");//交易流水号
                    if ("0".equals(encryptType)) {
                        String key = MD5.getMD5Code(appKey);
                        mobile = AESUtils.decrypt(mobile, key.substring(0, 16), key.substring(16));
                    } else if ("1".equals(encryptType)) {
                        mobile = RSAUtils.decryptByPrivateKeyForLongStr(mobile, PRIVATE_KEY);
                    }
                    LbbMember member = selectByPhone(mobile);
                    if (member != null) {

                        insertLoginRecord(member.getPhone(), requsetHeader);
                        if (checkImeiAndPhone(member.getPhone(), requsetHeader)) {
                            return Callback.fail("invalid_code", "一个设备只能登录一个手机号");
                        }

                        //销户账号再次注册登录
                        if (member.getStatus().equals(UserStatus.CheckSuccess.name())) {
                            member.setStatus(UserStatus.Allow.name());
                            updateMemberById(member);
                        }
                        insertMemberHeaderInfo(requsetHeader);
                        return Callback.success("200", "登录成功", member);
                    } else {
                        if (checkImei(requsetHeader.getImei())) {
                            return Callback.fail("invalid_code", "一个设备号最多注册1个账号,有疑问请联系客服");
                        }

                        insertLoginRecord(mobile, requsetHeader);
                        if (checkImeiAndPhone(mobile, requsetHeader)) {
                            return Callback.fail("invalid_code", "一个设备只能登录一个手机号");
                        }

                        //自动注册 密码为UUID随机值
                        member = createMember(request, requsetHeader, mobile);

                        insertDeviceInfo(parameter, member.getMemberId());
                        requsetHeader.setUserid(member.getMemberId());
                        insertMemberHeaderInfo(requsetHeader);
                        return Callback.success("200", "登录成功", member);
                    }
                }
            } else {
                return Callback.fail("200", "请求失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Callback.fail("200", "请求失败", e);
        } finally {
            redisClient.releaseDistributedLock("LOCK:IMEI:FASTLOGIN" + requsetHeader.getImei(), UUID);
        }
        return Callback.fail("200", "请求失败");

    }


    /**
     * 写入用户头部信息
     *
     * @param requestHeaders
     */
    public void insertMemberHeaderInfo(RequestHeaders requestHeaders) {
        MemberHeaderHistory memberHeaderHistory = new MemberHeaderHistory(requestHeaders);
        Integer count = memberHeaderHistoryMapper.countByMemberId(requestHeaders.getUserid());
        if (count == 0) {
            memberHeaderHistoryMapper.insertSelective(memberHeaderHistory);
        } else {
            memberHeaderHistoryMapper.updateByMemberId(memberHeaderHistory);
        }
    }

    /**
     * 写入快捷登录记录
     *
     * @param memberId
     * @param i
     */
    private void insertRecord(String memberId, int i) {
        FastLoginRecord fastLoginRecord = new FastLoginRecord();
        fastLoginRecord.setCreatedTime(new Date());
        fastLoginRecord.setMemberId(memberId);
        fastLoginRecord.setType(i);
        fastLoginRecordMapper.insertSelective(fastLoginRecord);
    }

    /**
     * 异步写入设备信息
     *
     * @param params
     * @param memberId
     */
    @Async
    public void insertDeviceInfo(String params, String memberId) {
        if (TextUtil.isEmpty(params) || memberDeviceInfoMapper.countByMemberId(memberId) > 0) {
            return;
        }
        MemberDeviceInfo info = JSON.parseObject(params, MemberDeviceInfo.class);
        info.setMemberId(memberId);
        memberDeviceInfoMapper.insert(info);

    }

    /**
     * 用户注册初始化钱包
     *
     * @param memberId
     */
    private void initWalletData(String memberId) {
        long lift = 0;
        long all = 0;
        Integer successCount = 0;
        Integer failCount = 0;
        MemberWallet wallet = new MemberWallet();
        wallet.setCreateTime(LocalDateTime.now());
        wallet.setModifyTime(LocalDateTime.now());
        wallet.setHasDeleted(0);
        wallet.setSuccessCount(successCount);
        wallet.setMemberId(memberId);
        wallet.setFailCount(failCount);
        wallet.setAllMoney(all);
        wallet.setAllCash(lift);
        wallet.setMoney(0L);
        wallet.setRebateMoney(0);
        wallet.setRevision(0L);
        memberWalletMapper.insertSelective(wallet);
    }

    /**
     * 用户注册初始化金币
     *
     * @param memberId
     */
    private void initPointData(String memberId) {

        MemberPointInfo info = new MemberPointInfo();
        info.setCreateTime(new Date());
        info.setModifyTime(new Date());
        info.setMemberId(memberId);
        info.setCount(0);
        info.setTotalCount(0);
        info.setTotalCash(0);
        info.setTodayCount(0);
        memberPointInfoMapper.insertSelective(info);
    }


    public LbbMember selectByOpenId(String openId) {
        return memberMapper.selectByOpenId(openId);
    }

    /**
     * 创建新用户对象
     *
     * @param request       请求
     * @param requsetHeader 请求头
     * @return
     */
    public LbbMember createMemberInfo(HttpServletRequest request, RequestHeaders requsetHeader, WeixinInfo weixinInfo,String city) throws Exception {

        String icode = inviteCode();
        String pass = UUIDUtil.L();
        String memberId = UUIDUtil.L();
        LbbMember member = new LbbMember();
        member.setRequestUri(request.getRequestURI());
        member.setCreateTime(new Date());
        member.setBrand(requsetHeader.getBrand());
        member.setImei(requsetHeader.getImei());
        member.setAppStore(requsetHeader.getAppStore());
        member.setAlipay("");
        member.setAlipayName("");
        member.setAppId(requsetHeader.getAppid());
        member.setAvatar(weixinInfo.getAvatar());
        member.setBirthday("");
        member.setCategory("True");
        member.setInviteCode(icode);
        member.setInviterId("");
        member.setMemberId(memberId);
        member.setNickname(weixinInfo.getNickName());
        member.setPassword(MessageDigestUtil.encryptMD5(pass.getBytes()));
        member.setPersonId("");
        member.setPhone("");
        member.setRealname("");
        member.setStatus("");
        member.setUnionid("");
        member.setWeixin("");
        member.setWeixinName("");
        member.setOsVersion(requsetHeader.getOsVersion());
        member.setOsv(requsetHeader.getOsv());
        member.setInviteVersion(InviteEnum.OLD_VERSION.getIndex());
        member.setIsGraduate(InviteEnum.UN_GRADUATION.getIndex());
        member.setWxOpenid(weixinInfo.getOpenId());
        member.setWxStatus(weixinInfo.getStatus());
        member.setGender(weixinInfo.getGender());
        member.setCity(city);

        IpAdressModel ipAddr = this.getIpAddr(requsetHeader.getIpAddr());
        member.setIpProvince(ipAddr.getProvince());
        member.setIpCity(ipAddr.getCity());

        insertMember(member);
        initWalletData(member.getMemberId());
        initPointData(member.getMemberId());
        return member;
    }

    public int updateByMemberId(String userid, String phone) {
        return memberMapper.updateByMemberId(userid, phone);
    }

    @Autowired
    private NewRewardMemberRecordMapper newRewardMemberRecordMapper;

    public boolean checkReward(String memberId) {
        int i = newRewardMemberRecordMapper.checkByMemberId(memberId);
        if (i == 0) {
            NewRewardMemberRecord rewardMemberRecord = new NewRewardMemberRecord();

            rewardMemberRecord.setCreateTime(LocalDateTime.now());
            rewardMemberRecord.setModifyTime(LocalDateTime.now());
            rewardMemberRecord.setHasDeleted("False");
            rewardMemberRecord.setMemberId(memberId);
            newRewardMemberRecordMapper.insertSelective(rewardMemberRecord);
        }
        return i == 0;
    }

    public int updateStatusByList(String status, List<String> list) {
        return memberMapper.updateStatusByList(status,list);
    }
}